#pragma once

namespace pb { namespace cfg {

    class CfgMgr;
    class Value;

    class Config
    {
        friend class CfgMgr;
    
    private:
        Config(const std::wstring& filePath);
        ~Config();

    public:
        bool setValue(const std::string& name, const std::string& value);
        bool getValue(const std::string& name, std::string& value);

        bool setValue(const std::string& name, const __int32 value);
        bool getValue(const std::string& name, __int32& value);

        void onValueChanged();
        const std::wstring& filePath() const;

    private:
        bool dirty() const;

        bool load();
        void save();

    private:
        bool loadHead(std::fstream&);
        bool loadData(std::fstream&);
        bool loadTail(std::fstream&);

        void saveHead(std::fstream&);
        void saveData(std::fstream&);
        void saveTail(std::fstream&);

        void clear();

        Value* newValue(const std::string& name, const char type);

    private:
        typedef std::map<std::string, Value*> ValueSet;

        const std::wstring  m_filePath;
        bool                m_loaded;
        bool                m_dirty;
        ValueSet            m_valueSet;
    };
    
}}